<template>
  <div class="choose-location-container">
    <div class="fill-container">
      <a-input
        placeholder="请输入经度"
        class="location-input"
        v-model="long"
        disabled
      ></a-input>
      <a-input
        placeholder="请输入纬度"
        class="location-input"
        v-model="lat"
        disabled
      ></a-input>
      <a-button type="primary" @click="reset()" v-if="mode != 'view'">
        重置
      </a-button>
    </div>
    <div class="map-container">
      <div class="map-dom" :id="getUUID(32, 32)" ref="mapDom"></div>
      <div class="map-condition-warp" v-if="mode != 'view'">
        <a-radio-group v-model="radio">
          <a-radio :value="1"> 按关键字 </a-radio>
          <a-radio :value="2"> 按坐标 </a-radio>
        </a-radio-group>
        <div class="input-warp">
          <div class="input flex" v-if="radio == 1">
            <a-input placeholder="请输入关键字" v-model="mapKeyword"></a-input>
          </div>
          <div class="input flex" v-if="radio == 2">
            <a-input
              placeholder="请输入经度"
              type="number"
              v-model="mapLong"
            ></a-input>
            <div class="split">，</div>
            <a-input
              placeholder="请输入纬度"
              type="number"
              v-model="mapLat"
            ></a-input>
          </div>
          <div class="btn" @click="mapSearch()">
            <bj-icon-font type="search" :size="22" color="#fff"></bj-icon-font>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
import { getProInitGeo, _getUUID } from "@/utils";
export default {
  model: {
    prop: "value",
    event: "input",
  },
  props: {
    value: {
      type: String,
      default: "",
    },
    mode: {
      type: String,
      default: "operate",
    },
  },
  data() {
    return {
      mapInstance: null,
      radio: 1,
      long: "",
      lat: "",
      mapKeyword: "",
      mapLong: "",
      mapLat: "",
    };
  },
  watch: {
    value: {
      handler(val) {
        if (val) {
          let [long, lat] = val.split(",");
          let { mapInstance } = this;
          this.long = long;
          this.lat = lat;
          if (this.isAMapPoint(long, lat)) {
            if (!mapInstance) {
              this.$nextTick((_) => {
                this.initMap().then((res) => {
                  this.drawMarker([long, lat]);
                  this.mapInstance.setFitView();
                });
              });
            } else {
              this.drawMarker([long, lat]);
              this.mapInstance.setFitView();
            }
          }
        } else {
          this.long = "";
          this.lat = "";
          this.$nextTick((_) => {
            this.initMap();
          });
        }
      },
      immediate: true,
    },
  },
  mounted() {},
  methods: {
    getUUID: _getUUID,
    //地图实例化
    initMap() {
      return new Promise((resolve) => {
        let { mode } = this;
        this.mapInstance = new AMap.Map(this.$refs.mapDom, {
          zoom: 15,
          center: this.validateDefaultPoint(),
        });
        //监听地图加载完成
        this.mapInstance.on("complete", () => {
          resolve();
        });

        //绑定点击事件
        mode != "view" &&
          this.mapInstance.on("click", (e) => {
            let [long, lat] = this.getLocationByClick(e);
            this.mapInstance.clearMap();
            this.mapLong = long;
            this.mapLat = lat;
          });
      });
    },

    //验证默认坐标
    validateDefaultPoint() {
      let { value } = this;
      if (!value) {
        return getProInitGeo();
      } else {
        let [lng, lat] = value.split(",");
        if (this.isAMapPoint(lng, lat)) {
          return [lng, lat];
        } else {
          return getProInitGeo();
        }
      }
    },

    //地图搜索
    mapSearch() {
      let {
        mapKeyword = "",
        radio,
        mapInstance,
        mapLong = "",
        mapLat = "",
      } = this;
      let that = this;

      if (radio == 1) {
        //按关键字搜索
        if (!mapKeyword.replace(/\s+/g, "") || !mapInstance) return;
        mapInstance.plugin(["AMap.PlaceSearch"], function () {
          var placeSearch = new AMap.PlaceSearch({
            city: "全国",
            citylimit: true,
            autoFitView: true,
          });
          placeSearch.search(mapKeyword, async function (status, result) {
            if (status == "complete") {
              if (result.poiList.pois.length == 0) {
                return;
              }
              result.poiList.pois.forEach((v) => {
                let { location, name } = v;
                that.drawMarker([location?.lng, location?.lat], name);
              });
              mapInstance.setFitView();
            }
          });
        });
      } else {
        //根据经纬度搜索
        let lngReg = /^-?(0|[1-9]\d*)(\.\d+)?$/;
        let latReg = /^-?([0-8]?\d(\.\d+)?|90(\.0+)?)$/;
        if (!(mapLong + "").trim() || !(mapLat + "").toString().trim()) {
          this.$message.warning("请输入经纬度坐标");
          return;
        }
        if (!lngReg.test(mapLong.toString())) {
          return this.$message.warning("经度不符合规范");
        }
        if (!latReg.test(mapLat.toString())) {
          return this.$message.warning("纬度不符合规范");
        }
        //清楚所有覆盖物
        mapInstance.clearMap();
        this.long = mapLong;
        this.lat = mapLat;
        that.drawMarker([mapLong, mapLat], "");
        mapInstance.setFitView();
      }
    },

    //绘制marker
    drawMarker(position = [], name = "") {
      if (!Array.isArray(position) || position.length == 0) {
        return;
      }
      var marker = new AMap.Marker({
        position,
        icon: new AMap.Icon({
          image:
            "//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png",
          size: new AMap.Size(30, 38), //设置icon的大小
          imageSize: new AMap.Size(30, 38),
        }),

        anchor: "bottom-center",
        offset: new AMap.Pixel(0, 0),
      });
      marker.setMap(this.mapInstance);
      //编订点击事件
      this.mode != "view" &&
        marker.on("click", (e) => {
          this.getLocationByClick(e);
        });
    },

    //点击获取坐标
    getLocationByClick(e = {}) {
      if (this.disabled) {
        return;
      }
      let { lnglat } = e;
      this.long = lnglat?.lng;
      this.lat = lnglat?.lat;
      this.$emit("input", `${this.long},${this.lat}`);
      return [this.long, lnglat?.lat];
    },

    //验证坐标是否合法
    isAMapPoint(lng, lat) {
      const lngRegExp = /^-?(0|[1-9]\d*)(\.\d+)?$/;
      const latRegExp = /^-?([0-8]?\d(\.\d+)?|90(\.0+)?)$/;
      return lngRegExp.test(lng.toString()) && latRegExp.test(lat.toString());
    },

    //重置
    reset() {
      this.mapInstance.clearMap();
      this.long = "";
      this.lat = "";
      this.mapLong = "";
      this.mapLat = "";
      this.mapKeyword = "";
      this.$emit("input", "");
    },
  },
  destroyed() {
    let { mapInstance } = this;
    mapInstance && mapInstance.destroy();
    this.mapInstance = null;
  },
};
</script>
<style lang="less" scoped>
.choose-location-container {
  width: 100%;
  .flex();
  flex-direction: column;
  .fill-container {
    .flex();
    height: 50px;
    /deep/.ant-input {
      margin-right: 10px;
      &[disabled] {
        background: #fff;
        border: 1px solid #d4d4d4;
      }
    }
    button {
      flex-shrink: 0;
      margin: 0;
    }
  }
  .map-container {
    height: 340px;
    background: #ffffff;
    border: 1px solid #dcdee2;
    border-radius: 4px;
    overflow: hidden;
    position: relative;
    .map-dom {
      width: 100%;
      height: 100%;
      position: absolute;
      top: 0;
      left: 0;
      z-index: 9;
    }
    .map-condition-warp {
      width: 460px;
      background: #ffffff;
      box-shadow: 0px 1px 3px 0px rgba(93, 93, 93, 0.34);
      border-radius: 4px;
      position: absolute;
      top: 10px;
      left: 10px;
      z-index: 99;
      box-sizing: border-box;
      padding: 0 16px;
      .input-warp {
        .flex();
        height: 30px;
        border-radius: 4px;
        overflow: hidden;
        margin-bottom: 10px;
        .input {
          flex: 1;
          border: 1px solid #d4d7d8;
          border-radius: 4px 0 0 4px;
          border-right: 0;
          align-items: center;
          input {
            height: 100%;
            border: none;
            &:focus {
              box-shadow: none;
            }
          }
        }
        .btn {
          width: 45px;
          flex-shrink: 0;
          .flex();
          align-items: center;
          justify-content: center;
          background: var(--primary-color);
          cursor: pointer;
        }
      }
    }
  }
}
</style>
